package com.somekim.mythread;

/**
 * 实例变量与线程安全 - 数据共享
 * @author zdl
 * @version v1.0
 * @date 2019/8/27
 */
public class MyThread5 extends Thread{
    /**
     * 共享数据的情况就是多个线程可以访问同一个变量。
     */
    private int count = 5;

    /**
     * 通过在run方法前加synchronized关键字，使多个线程在执行run方法时，以排队的方式进行
     * 处理。当一个线程调用run前，先判断run方法有没有被上锁，如果上锁，说明有其他线程正在
     * 调用run方法，必须等其他线程对run方法调用结束后才可以执行run方法。
     * 这样也就实现了排队调用run方法的目的，也就达到了按顺序对count变量减1的效果了。
     * synchronized可以在任意对象及方法上加锁，而加锁的这段代码称为“互斥区”或“临界区”。
     * 当一个线程想要执行同步方法里面的代码时，线程首先尝试去拿这把锁，如果能够拿到这把锁，
     * 那么这个线程就可以执行synchronize里面的代码。如果不能拿到这把锁，那么这个线程就会
     * 不断地尝试拿这把锁，直到能够拿到为止，而且是有多个线程同时去争抢这把锁。
     */
    @Override
//    synchronized
    public void run() {
        super.run();
        count--;
        //此示例不要用for语句，因为使用同步后其他线程就得不到运行的机会了
        //一直由一个线程进行减法运算
        System.out.println("由 " + MyThread5.currentThread().getName() + " 计算，count=" + count);
    }

    public static void main(String[] args) {
        MyThread5 myThread5 = new MyThread5();
        Thread a = new Thread(myThread5, "A");
        Thread b = new Thread(myThread5, "B");
        Thread c = new Thread(myThread5, "C");
        Thread d = new Thread(myThread5, "D");
        Thread e = new Thread(myThread5, "E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}
